package com.yunlong.softpark.service.impl;

import com.yunlong.softpark.core.exception.SysException;
import com.yunlong.softpark.dto.*;
import com.yunlong.softpark.entity.*;
import com.yunlong.softpark.form.PublishedForm;
import com.yunlong.softpark.form.UpdateSoftForm;
import com.yunlong.softpark.mapper.ColumnMapper;
import com.yunlong.softpark.mapper.SoftwareMapper;
import com.yunlong.softpark.mapper.UserMapper;
import com.yunlong.softpark.service.SoftwareService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Author: Cui
 * @Date: 2020/7/24
 * @Description:
 */
@Slf4j
@Service
public class SoftwareServiceImpl implements SoftwareService {

    @Autowired
    SoftwareMapper softwareMapper;

    @Autowired
    ColumnMapper columnMapper;

    @Autowired
    UserMapper userMapper;

    /**
     * 获取首页软件
     *
     * @return
     */
    @Override
    public FirstMajorDto getFirstMajor() {
        //添加综合推荐到列表
        FirstMajor firstMajor = new FirstMajor();
        firstMajor.setPlateName("综合推荐");
        List<MajorColumn> majorColumns = new ArrayList<>();
        List<ColumnEntity> columnEntities = softwareMapper.getRecommend();
        for (ColumnEntity c : columnEntities) {
            MajorColumn majorColumn = new MajorColumn();
            majorColumn.setColumnLogo(c.getColumnLogo());
            majorColumn.setColumnName(c.getColumnName());
            majorColumn.setDownloads(c.getDownloads());
            majorColumn.setColumnId(c.getColumnId());
            majorColumns.add(majorColumn);
        }
        firstMajor.setSonList(majorColumns);
        FirstMajorDto firstMajorDto = new FirstMajorDto();
        List<FirstMajor> firstMajors = new ArrayList<>();
        List<PlatesEntity> plates = softwareMapper.getPlates(4);
        List<SortEntity> sortEntities = softwareMapper.getSort();
        List<ColumnEntity> columnBySort = softwareMapper.getColumn();
        //匹配三级菜单到一级菜单
        firstMajors = plates.stream().map((p) -> {
            FirstMajor fm = new FirstMajor();
            fm.setPlateName(p.getPlateName());
            List<MajorColumn> l = new ArrayList<>();
            sortEntities.stream().filter((s) ->
                    s.getParentId() == p.getPlateId()
            ).forEach((c) -> {
                columnBySort.stream().filter((columnEntity) ->
                        columnEntity.getParentId() == c.getSortId()
                ).map((x) -> {
                    MajorColumn majorColumn = new MajorColumn();
                    majorColumn.setColumnLogo(x.getColumnLogo());
                    majorColumn.setColumnName(x.getColumnName());
                    majorColumn.setDownloads(x.getDownloads());
                    majorColumn.setColumnId(x.getColumnId());
                    l.add(majorColumn);
                    return majorColumn;
                }).collect(Collectors.toList());
            });
            fm.setSonList(l);
            return fm;
        }).collect(Collectors.toList());
        firstMajors.add(0, firstMajor);
        firstMajorDto.setFirstMajors(firstMajors);
        return firstMajorDto;
    }

    /**
     * 获取分类页面的软件主体及板块分类
     *
     * @return
     */
    @Override
    public ColumnSortDto getMajorSoft(Integer page, Integer plateId) {
        //从数据库中查取板块，分类，栏目
//        List<PlatesEntity> platesEntities = softwareMapper.getPlates(100);
//        List<SortEntity> sortEntities = softwareMapper.getSort();
//        List<ColumnEntity> columnEntities = softwareMapper.getColumn();
//        //封装三级菜单
//        List<MajorPlate> majorPlates = platesEntities.stream().map((p)->{
//            MajorPlate majorPlate = new MajorPlate();
//            majorPlate.setPlateName(p.getPlateName());
//            List<MajorSort> majorSorts = sortEntities.stream().map((s)->{
//                MajorSort majorSort = new MajorSort();
//                majorSort.setSortName(s.getSortName());
//                majorSort.setSortId(s.getSortId());
//                List<MajorColumn> majorColumns = columnEntities.stream().map((c)->{
//                    MajorColumn majorColumn = new MajorColumn();
//                    majorColumn.setColumnId(c.getColumnId());
//                    majorColumn.setDownloads(c.getDownloads());
//                    majorColumn.setColumnName(c.getColumnName());
//                    majorColumn.setColumnLogo(c.getColumnLogo());
//                    return majorColumn;
//                }).collect(Collectors.toList());
//                majorSort.setMajorColumns(majorColumns);
//                return majorSort;
//            }).collect(Collectors.toList());
//            majorPlate.setMajorSorts(majorSorts);
//            return majorPlate;
//        }).collect(Collectors.toList());
//        SoftMajorDto softMajorDto = new SoftMajorDto();
//        softMajorDto.setPlatesEntities(majorPlates);
//        return softMajorDto;

        List<PlatesEntity> platesEntities = softwareMapper.getPlates(100);
//        Integer platesMinId = getPlatesMin(platesEntities);
        //根据板块id查询子分类
        SearchSortByPlateDto sortEntities = getSort(plateId);
        Integer sortMinId = getSortMin(sortEntities.getSearchSortByPlates());
        //根据分类id查询子栏目
        List<MajorColumn> columnEntities = getColumnBySort(sortMinId, page).getSearchColumns();
        ColumnSortDto columnSortDto = new ColumnSortDto();
        //构造返回值
        columnSortDto.setColumnEntities(columnEntities);
        columnSortDto.setPlatesEntities(platesEntities);
        columnSortDto.setSortEntities(sortEntities.getSearchSortByPlates());
        return columnSortDto;
    }


    /**
     * 通过分类id得到column
     *
     * @param sortId
     * @return
     */
    @Override
    public SearchColumnDto getColumnBySort(Integer sortId, Integer page) {
        List<ColumnEntity> columnEntities = softwareMapper.getColumnEntity(sortId, (page - 1) * 25);
        List<MajorColumn> searchColumns = new ArrayList<>();
        for (ColumnEntity c : columnEntities) {
            MajorColumn searchColumn = new MajorColumn();
            searchColumn.setColumnId(c.getColumnId());
            searchColumn.setColumnLogo(c.getColumnLogo());
            searchColumn.setDownloads(c.getDownloads());
            searchColumn.setColumnName(c.getColumnName());
            searchColumns.add(searchColumn);
        }
        SearchColumnDto searchColumnDto = new SearchColumnDto();
        searchColumnDto.setSearchColumns(searchColumns);
        return searchColumnDto;
    }

    /**
     * 更新下载次数
     *
     * @param softId
     */
    @Override
    public void download(String softId) {
        SoftwareEntity softwareEntity = softwareMapper.selectBySoftId(softId);
        int downloads = softwareEntity.getDownloads();
        downloads++;
        softwareMapper.UpdateDownloads(softId, downloads);
        ColumnEntity columnEntity = columnMapper.selectByColumnId(softwareEntity.getParentId());
        int columnEntityDownloads = columnEntity.getDownloads();
        columnEntityDownloads++;
        columnMapper.UpdateDownloads(columnEntity.getColumnId(), columnEntityDownloads);
    }

    /**
     * 发布页面的三级菜单
     *
     * @return
     */
    @Override
    public PublishMenuDto publishMenu() {
        PublishMenuDto publishMenuDto = new PublishMenuDto();
        //从数据库中查询板块，分类和栏目
        List<PlatesEntity> plates = softwareMapper.getPlates(100);
        List<SortEntity> sort = softwareMapper.getSort();
        List<ColumnEntity> column = softwareMapper.getColumn();
        //封装三级菜单
        AtomicInteger i= new AtomicInteger();
        int j=0;
        List<MenuList> menuLists = plates.stream().map((p)->{
            List<MenuList> collect1 = sort.stream().filter((s) ->
                    s.getParentId() == p.getPlateId()
            ).map((s) -> {
                List<MenuList> collect = column.stream().filter((c) ->
                        c.getParentId() == s.getSortId()
                ).map((c) -> {
                    MenuList menuList = new MenuList();
                    menuList.setMenuName(c.getColumnName());
                    menuList.setColumnId(c.getColumnId());
                    return menuList;
                }).collect(Collectors.toList());
                MenuList menuList = new MenuList();
                menuList.setMenuName(s.getSortName());
                menuList.setSonList(collect);
                menuList.setColumnId(s.getSortId()+"");
                return menuList;
            }).collect(Collectors.toList());
            for(i.set(0); i.get() <collect1.size(); i.getAndIncrement()){
                collect1.get(i.get()).setColumnId(i.get()+"");
            }
            MenuList menuList = new MenuList();
            menuList.setMenuName(p.getPlateName());
            menuList.setSonList(collect1);
            menuList.setColumnId((p.getPlateId()-1)+"");
            return menuList;
        }).collect(Collectors.toList());
        publishMenuDto.setMenuLists(menuLists);
        return publishMenuDto;
    }


    /**
     * 发布软件
     *
     * @param publishedForm
     * @param userId
     * @return
     */
    @Override
    public String publishedSoft(PublishedForm publishedForm, String userId) {

        SoftwareEntity softwareEntity = new SoftwareEntity();
        softwareEntity.setBriefIntro(publishedForm.getBriefIntro());
        softwareEntity.setCreateTime(new Date());
        softwareEntity.setDownloads(0);
        softwareEntity.setEdition(publishedForm.getEdition());
        softwareEntity.setInstallProleft(publishedForm.getInstallProleft());
        softwareEntity.setInstallProright(publishedForm.getInstallProright());
        softwareEntity.setLanguage(publishedForm.getLanguage());
        softwareEntity.setParentId(publishedForm.getParentId());
        softwareEntity.setShowPic(publishedForm.getShowPic());
        softwareEntity.setPlatform(publishedForm.getPlatform());
        softwareEntity.setSoftAddr(publishedForm.getSoftAddr());
        softwareEntity.setSoftId(UUID.randomUUID().toString().replace("-", ""));
        softwareEntity.setSoftLogo(publishedForm.getSoftLogo());
        softwareEntity.setUpdateTime(new Date());
        softwareEntity.setUserId(userId);
        softwareEntity.setVerify(0);
        softwareEntity.setSoftName(publishedForm.getSoftName());
        softwareEntity.setSoftSize(publishedForm.getSoftSize());
        softwareMapper.insertSoft(softwareEntity.getBriefIntro(), softwareEntity.getCreateTime(),
                softwareEntity.getDownloads(), softwareEntity.getEdition(), softwareEntity.getInstallProleft(),
                softwareEntity.getInstallProright(), softwareEntity.getLanguage(), softwareEntity.getParentId(),
                softwareEntity.getPlatform(), softwareEntity.getShowPic(), softwareEntity.getSoftAddr(),
                softwareEntity.getSoftId(), softwareEntity.getSoftLogo(), softwareEntity.getSoftName(),
                softwareEntity.getSoftSize(), softwareEntity.getUpdateTime(), softwareEntity.getUserId(),
                softwareEntity.getVerify());
        return softwareEntity.getUserId();
    }

    /**
     * 模糊搜索
     *
     * @param key
     * @return
     */
    @Override
    public SearchDto search(String key) {
        List<String> columnIds = new ArrayList<>();
        List<SoftwareEntity> softwareEntities = softwareMapper.selectByKey(key);
        List<SearchSoft> searchDtos = new ArrayList<>();
        for (SoftwareEntity s : softwareEntities) {
            SearchSoft searchSoft = new SearchSoft();
            BeanUtils.copyProperties(s,searchSoft);
            searchSoft.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                    .format(s.getCreateTime()));
            searchDtos.add(searchSoft);
        }
        List<ColumnEntity> columnEntities = softwareMapper.getColumn();
        List<ColumnEntity> collect1 = columnEntities.stream().filter((c) ->
                c.getColumnName().matches(".*" + key + ".*") || c.getColumnType().matches(".*" + key + ".*")
                        || c.getWebIntroduce().matches(".*" + key + ".*")
        ).map((c)->{
            columnIds.add(c.getColumnId());
            return c;
        }).collect(Collectors.toList());
        List<SortEntity> sortEntities = softwareMapper.getSort();
        List<SortEntity> sorts = sortEntities.stream().filter((s) ->
                s.getSortName().matches(".*" + key + ".*")
        ).collect(Collectors.toList());
        for (SortEntity s : sorts) {
            List<ColumnEntity> collect = columnEntities.stream().filter((c) ->
                    s.getSortId() == c.getParentId()
            ).collect(Collectors.toList());
            for (ColumnEntity c : collect){
                if(!columnIds.contains(c.getColumnId())){
                    collect1.add(c);
                    columnIds.add(c.getColumnId());
                }
            }
        }
        List<SearchColumn> collect = collect1.stream().map((c) -> {
            SearchColumn column = new SearchColumn();
            BeanUtils.copyProperties(c, column);
            return column;
        }).collect(Collectors.toList());
        SearchDto searchDto = new SearchDto();
        searchDto.setSearchSofts(searchDtos);
        searchDto.setSearchColumns(collect);
        return searchDto;
    }

    public static void main(String[] args) {
        String s = "社交平台";
        System.out.println(s.matches(".*社交.*"));
    }
    /**
     * 通过板块id获取分类
     *
     * @param plateId
     * @return
     */
    @Override
    public SearchSortByPlateDto getSort(Integer plateId) {

        List<SortEntity> sortEntities = softwareMapper.selectSortByPlate(plateId);
        SearchSortByPlateDto searchSortByPlateDto = new SearchSortByPlateDto();
        List<MajorSort> majorSorts = new ArrayList<>();
        for (SortEntity s : sortEntities) {
            MajorSort majorSort = new MajorSort();
            majorSort.setSortId(s.getSortId());
            majorSort.setSortName(s.getSortName());
            majorSorts.add(majorSort);
        }
        searchSortByPlateDto.setSearchSortByPlates(majorSorts);
        return searchSortByPlateDto;
    }

    /**
     * 获取板块中最小的id
     *
     * @param platesEntities
     * @return
     */
    private Integer getPlatesMin(List<PlatesEntity> platesEntities) {
        int min = 100;
        for (PlatesEntity p : platesEntities) {
            min = min < p.getPlateId() ? min : p.getPlateId();
        }
        return min;
    }

    /**
     * 获取分类中最小的id
     *
     * @param majorSort
     * @return
     */
    private Integer getSortMin(List<MajorSort> majorSort) {
        int min = 100;
        for (MajorSort m : majorSort) {
            min = min < m.getSortId() ? min : m.getSortId();
        }
        return min;
    }

    /**
     * 返回在栏目下栏展示的软件集信息
     *
     * @param columnId
     * @return
     */
    @Override
    public List<SoftwareSimpVersionDto> getSimpVersionIntroduce(String columnId) {
        List<SoftwareEntity> list = softwareMapper.selectByColumnId(columnId);
        List<SoftwareSimpVersionDto> list1 = new ArrayList<>();
        try {
            for (SoftwareEntity softwareEntity : list) {
                if (softwareEntity.getVerify() == 1) {
                    SoftwareSimpVersionDto ssvd = new SoftwareSimpVersionDto();
                    ssvd.setSoftId(softwareEntity.getSoftId());
                    ssvd.setSoftName(softwareEntity.getSoftName());
                    ssvd.setSoftLogo(softwareEntity.getSoftLogo());
                    ssvd.setDownloads(softwareEntity.getDownloads());
                    ssvd.setEdition(softwareEntity.getEdition());
                    ssvd.setPlatform(softwareEntity.getPlatform());
                    ssvd.setSoftAddr(softwareEntity.getSoftAddr());
                    ssvd.setSoftSize(softwareEntity.getSoftSize());
                    ssvd.setBriefIntro(softwareEntity.getBriefIntro());

                    Date date = softwareEntity.getUpdateTime();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String time = sdf.format(date);
                    ssvd.setUpdateTime(time);
                    list1.add(ssvd);
                }
            }
        } catch (NullPointerException e) {
            System.out.println("查询失败或者数据空信息空！");
        }

        return list1;
    }

    /**
     * 返回在软件点开栏上栏显示的软件简介信息
     *
     * @param softId
     * @return
     */
    @Override
    public SoftwareSimpIntroDto getSimpIntroduc(String softId) {
        SoftwareEntity softwareEntity = softwareMapper.selectBySoftId(softId);
        String columnId = softwareEntity.getParentId();
        ColumnSimDto simDto = columnMapper.selectDataForSimpleColumn(columnId);
        SoftwareSimpIntroDto simpIntroDto = new SoftwareSimpIntroDto();
        try {
            simpIntroDto.setSoftName(softwareEntity.getSoftName());
            simpIntroDto.setBriefIntro(softwareEntity.getBriefIntro());
            simpIntroDto.setColumnWeb(simDto.getColumnWeb());
            simpIntroDto.setDownloads(softwareEntity.getDownloads());
            simpIntroDto.setEdition(softwareEntity.getEdition());
            simpIntroDto.setShowPic(softwareEntity.getShowPic());
            simpIntroDto.setSoftLogo(softwareEntity.getSoftLogo());
            simpIntroDto.setSoftSize(softwareEntity.getSoftSize());
            simpIntroDto.setPlatform(softwareEntity.getPlatform());
            simpIntroDto.setSoftAddr(softwareEntity.getSoftAddr());
        } catch (NullPointerException e) {
            System.out.println("查询失败或者数据空信息空！");
        }

        return simpIntroDto;
    }

    /**
     * 根据软件id返回软件的右安装步骤
     *
     * @param softId
     * @return
     */
    @Override
    public SoftwareDetailDto getDetailIntroduce(String softId) {
        SoftwareEntity softwareEntity = softwareMapper.selectBySoftId(softId);
        SoftwareDetailDto softwareDetailDto = new SoftwareDetailDto();
        try {
            softwareDetailDto.setInstallProRight(softwareEntity.getInstallProright());
        } catch (NullPointerException e) {
            System.out.println("查询失败或者数据空信息空！");
        }

        return softwareDetailDto;
    }

    /**
     * 根据前端传递的columnId和softId返回软件的信息
     * 点开栏下的基本信息
     *
     * @param softId
     * @return
     */
    @Override
    public SoftwareBaseDataDto getBaseData(String softId) {
        SoftwareBaseDataDto softwareBaseDataDto = new SoftwareBaseDataDto();


        SoftwareEntity softwareEntity = softwareMapper.selectBySoftId(softId);
        String columnWeb = columnMapper.selectDataForBaseData(softwareEntity.getParentId());
        UserEntity userEntity = userMapper.selectById(softwareEntity.getUserId());
        try {
            softwareBaseDataDto.setColumnWeb(columnWeb);
            softwareBaseDataDto.setUsername(userEntity.getUsername());
            softwareBaseDataDto.setLanguage(softwareEntity.getLanguage());
            softwareBaseDataDto.setEdition(softwareEntity.getEdition());
            softwareBaseDataDto.setSoftAddr(softwareEntity.getSoftAddr());
        } catch (NullPointerException e) {

        }
        return softwareBaseDataDto;
    }

    @Override
    public EditSoftDto editSoft(String softId,String userId) {
        SoftwareEntity softwareEntity = softwareMapper.selectBySoftId(softId);
        if(!softwareEntity.getUserId().equals(userId)){
            throw new SysException("编辑软件错误，登录用户非软件的发布者");
        }
        EditSoftDto editSoftDto = new EditSoftDto();
        editSoftDto.setBriefIntro(softwareEntity.getBriefIntro());
        editSoftDto.setEdition(softwareEntity.getEdition());
        editSoftDto.setInstallProleft(softwareEntity.getInstallProleft());
        editSoftDto.setInstallProright(softwareEntity.getInstallProright());
        editSoftDto.setLanguage(softwareEntity.getLanguage());
        editSoftDto.setPlatform(softwareEntity.getPlatform());
        editSoftDto.setShowPic(softwareEntity.getShowPic());
        editSoftDto.setSoftAddr(softwareEntity.getSoftAddr());
        editSoftDto.setSoftLogo(softwareEntity.getSoftLogo());
        editSoftDto.setSoftName(softwareEntity.getSoftName());
        editSoftDto.setSoftSize(softwareEntity.getSoftSize());
        PublishMenuDto publishMenuDto = publishMenu();
        List<MenuList> plateMenus = publishMenuDto.getMenuLists();
        editSoftDto.setPlateMenus(plateMenus);
        EditSoft editSoft = new EditSoft();
        editSoft.setColumnId(softwareEntity.getParentId());
        for(int i=0;i<plateMenus.size();i++){
            for(int j=0;j<plateMenus.get(i).getSonList().size();j++){
                for(int k=0;k<plateMenus.get(i).getSonList().get(j).getSonList().size();k++){
                    if(softwareEntity.getParentId().equals(plateMenus.get(i).getSonList().get(j).getSonList().get(k).getColumnId())){
                        editSoft.setPlateIndex(i+"");
                        editSoft.setSortIndex(j+"");
                    }
                }
            }
        }
        editSoftDto.setEditSoft(editSoft);
        return editSoftDto;
    }

    @Override
    public void deleteSoft(String softId,String userId) {
        SoftwareEntity softwareEntity = softwareMapper.selectBySoftId(softId);
        if(!userId.equals(softwareEntity.getUserId())){
            throw new SysException("删除软件错误，登录用户非软件发布人");
        }
        softwareMapper.deleteSoftById(softId);
    }

    @Override
    public MessageSuccessDto updateSoft(UpdateSoftForm updateSoftForm, String userId) {

        SoftwareEntity softwareEntity = softwareMapper.selectBySoftId(updateSoftForm.getSoftId());
        if(!softwareEntity.getUserId().equals(userId)){
            throw new SysException("系统错误");
        }
        softwareMapper.updateSoftById(updateSoftForm.getBriefIntro(),updateSoftForm.getEdition(),
                updateSoftForm.getInstallProleft(),updateSoftForm.getInstallProright(),
                updateSoftForm.getLanguage(),updateSoftForm.getParentId(),updateSoftForm.getPlatform(),
                updateSoftForm.getShowPic(),updateSoftForm.getSoftAddr(),updateSoftForm.getSoftId(),
                updateSoftForm.getSoftLogo(),updateSoftForm.getSoftName(),updateSoftForm.getSoftSize(),
                new Date());
        MessageSuccessDto messageSuccessDto = new MessageSuccessDto();
        messageSuccessDto.setMessage("修改成功！");
        return messageSuccessDto;
    }

}
